package com.love.cloud.common.core.handle;


import com.love.cloud.common.core.annotation.UnAdvice;
import com.love.cloud.common.core.config.ResponseHandlerConfig;
import com.love.cloud.common.core.util.JsonUtil;
import com.love.cloud.common.core.util.R;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author
 * @version 1.0
 */
//@ControllerAdvice(basePackages = "com.cn.**")*/
@ControllerAdvice(basePackages = "com.love.cloud")
//@ControllerAdvice(annotations = {RestController.class})
public class ResponseHandler implements ResponseBodyAdvice<Object> {

    @Resource
    private ResponseHandlerConfig responseHandlerConfig;

    public static List<String> regexList = null;

    /**
     * 是否支持advice功能
     * treu=支持，false=不支持
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    /**
     *
     * 处理response的具体业务方法
     */
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        //判断请求头中是否有unAdvice信息
        if(serverHttpRequest.getHeaders().get("unAdvice")!=null&&
                serverHttpRequest.getHeaders().get("unAdvice").size()>0&&
                serverHttpRequest.getHeaders().get("unAdvice").contains("yes")){
            return o;
        }
        UnAdvice annotation = methodParameter.getAnnotatedElement().getAnnotation(UnAdvice.class);
        if(annotation!=null){
            return o;
        }
        //获取到接口地址
        String path = serverHttpRequest.getURI().getPath();
        if (StringUtils.isNotEmpty(path)){
            //判断是否符合过滤的条件
            if(isPass(path)){
                //符合直接返回
                return o;
            }
        }
        if (o instanceof R) {
            return o;
        }else if(o instanceof SseEmitter){
            return o;
        } else if (o instanceof String) {
            return JsonUtil.object2Json(R.ok(o));
        }
        return R.ok(o);
    }


    /**
     * 正则匹配地址
     *
     * @param path
     * @return
     */
    private boolean isPass(String path) {
        Pattern pattern = null;
        String orginalUrl = path.split("[?]")[0];
        for (String regex : getRegexList()) {
            pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
            if (pattern.matcher(orginalUrl).matches()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取正则匹配规则list
     *
     * @return
     */
    private List<String> getRegexList() {
        //第一次加载这个,以及配置修改的时候加载这个(这个还没法实现，只能每次都加载)
        if (regexList == null) {
            regexList = new ArrayList<String>();
        }else{
            return regexList;
        }
        for (String url : responseHandlerConfig.getIgnorePaths()) {
            StringBuilder regex = new StringBuilder("\\S*").append(url.replace("/**", "\\S*")).append("\\S*");
            regexList.add(regex.toString());
        }
        return regexList;
    }
}

